#pragma once
#include <complex>
#include <functional>
#include <list>
#include <math.h>
#include <set>
#include <valarray>
#include <iostream>
#include <map>



class Position
{
public:
	Position() :Position(0, 0){}
	Position(int x, int y) { x_ = x;y_ = y; }
	bool operator<(const Position& rhs) const
	{
		if (x_<rhs.x_)
		{
			return true;
			
		}
		if (x_ == rhs.x_)
		{
			if (y_<rhs.y_)
			{
				return true;
			}
		}
		return false;
	}
	int x_;
	int y_;

};

class AstarNode
{
public:
	AstarNode() :AstarNode(0, 0) {}
	AstarNode(const int x, const int y)
	{
		x_ = x; y_ = y;
		isclosed_ = false;
		gn_ = 0;
		parentNode = nullptr;
		hn_ = std::abs(x - dest_x_) + std::abs(y - dest_y_);

		allNodes.insert(std::make_pair(Position(x_, y_), this));
	}
	AstarNode* parentNode;
	static std::map<Position, AstarNode*> allNodes;
	static std::list<AstarNode*> closedNodes;
	//static std::multiset<AstarNode*, std::function<bool(const AstarNode* n1, const AstarNode* n2)>> openNodes;
	static std::list<AstarNode*> openNodes;
	static AstarNode* getNode(int x , int y);
	static void resetNodes() { 
		
		openNodes.clear();
		for (auto i = allNodes.begin(); i != allNodes.end(); ++i)
		{
			delete (*i).second;
		}
		allNodes.clear();
	}
	static void SetDest(const int x, const int y) { dest_x_ = x; dest_y_ = y;}
	static void SetStart(const int x, const int y) { start_x_ = x; start_y_ = y;}
	static void SetField(const int x, const int y) { sizex = x;sizey = y;}
	static int smallfn;
	
	bool operator< (const AstarNode& other) const;
	
	bool isclosed_;
	int gn_;
	int hn_;
	int getFn() const;
	void findNext();
private:
	

	inline  bool isvalied(int x, int y) const;
	inline  AstarNode* findchild(int offsetx, int offsety);
	
	static  int dest_x_ ;
	static  int dest_y_ ;
	static  int start_x_ ;
	static  int start_y_ ;
	static  int sizex;
	static  int sizey;
	int x_ ;
	int y_ ;
};







